#pragma once

#include<iostream>
#include<string>
#include<functional>
#include<unistd.h>
#include"InetAddr.hpp"
#define LISTENLOCKET 0
#define NORMALSOCKET 1

/*  This is a class that encapsulates sockfd and provides 
    an interface that registers callback methods 
    to handle the corresponding events
*/
class Reactor;
class Connection;
using handle_t = std::function<void(Connection* con)>;

class Connection
{
public:
    Connection(int sockfd) : _sockfd(sockfd)
    {}
    //注册回调方法来处理已就绪事件
    void RegisEventCallback(handle_t recver,handle_t sender,handle_t error)
    {
        _recv_handle = recver;
        _send_handle = sender;
        _error_handle = error;
    }
    //构建事件
    void SetEvents(uint32_t events)
    {
        _events = events;
    }
    uint32_t Eevents()
    {
        return _events;
    }
    int SockFd()
    {
        return _sockfd;
    }
    int ConnectionType()
    {
        return _type;
    }
    void SetReactorPtr(Reactor* R)
    {
        _R = R;
    }
    void SetConnectionType(int type)
    {
        _type = type;
    }
    void SetInetAddr(const InetAddr& addr)
    {
        _addr = addr;
    }
    void AppendRecvBuffer(const std::string& in)
    {
        _recv_buffer += in;
    }
    void AppendSendBuffer(const std::string& out)
    {
        _send_buffer += out;
    }
    std::string SendBuffer()
    {
        return _send_buffer;
    }
    std::string& RecvBuffer()
    {
        return _recv_buffer;
    }
    void ClearBuffer(int n)
    {
        _send_buffer.erase(0,n);
    }
    ~Connection()
    {}
private:
    int _sockfd;        //sockfd
    uint32_t _events;   //fd Concerned Events
    std::string _recv_buffer;   //fd对应的接收缓冲区
    std::string _send_buffer;   //fd对应的发送缓冲区
    int _type;                  //套接字的类型
    InetAddr _addr;             //当前Connection的ip + port;
//回调处理事件
public:
    handle_t _recv_handle;  //handler read event
    handle_t _send_handle;  //handler write event
    handle_t _error_handle; //handler error event

public:
    Reactor* _R;            //声明自己指向的是那个Reactor对象!
};

